package com.turnengine.client.local.unit.list.count;

import java.util.ArrayList;
import java.util.List;

import com.turnengine.client.local.unit.IUnitCache;
import com.turnengine.client.local.unit.bean.IUnit;
import com.turnengine.client.local.unit.bean.IUnitCount;
import com.turnengine.client.local.unit.bean.UnitCount;
import com.turnengine.client.local.unit.enums.UnitNode;
import com.turnengine.client.local.unit.enums.UnitType;
import com.turnengine.client.local.unit.list.ChildUnit;
import com.turnengine.client.local.unit.list.IChildUnit;
import com.turnengine.client.local.unit.list.IParentUnit;
import com.turnengine.client.local.unit.list.IUnitList;
import com.turnengine.client.local.unit.list.ParentUnit;
import com.turnengine.client.local.unit.list.UnitList;

public class UnitListToCountListAdaptor implements IUnitListToCountListAdaptor {

	private final IUnitCache unitCache;

	public UnitListToCountListAdaptor(IUnitCache unitCache) {
		if (unitCache == null) {
			throw new NullPointerException("unitCache");
		}
		this.unitCache = unitCache;
	}

	@Override
	public IUnitList adapt(List<IUnitCount> countList, UnitType type) {
		IUnitList list = new UnitList(type);
		IParentUnit parent = null;
		for (IUnitCount count : countList) {
			int unitId = count.getId();
			IUnit unit = unitCache.getById(unitId);

			// Parent Unit
			if (unit.getNode().equals(UnitNode.PARENT)) {
				if (count.getAmount() <= 0) {
					throw new IllegalStateException("parent: " + unit + ", amount=" + count.getAmount() + " in " + countList);
				}
				for (int i = 0; i < count.getAmount(); i++) {
					parent = new ParentUnit(unitId);
					list.addParent(parent);
				}

				// If we find multiple parents, NONE of them can have children
				if (count.getAmount() > 1) {
					parent = null;
				}
			}

			// Child Unit
			else {
				if (parent == null) {
					throw new IllegalStateException("child unit without any parents in " + countList);
				}
				IChildUnit child = new ChildUnit(unitId, count.getAmount());
				parent.addChild(child);
			}
		}
		return list;
	}

	@Override
	public List<IUnitCount> adapt(IUnitList list) {
		List<IUnitCount> countList = new ArrayList<IUnitCount>();
		for (IParentUnit parent : list.getParents()) {
			countList.add(new UnitCount(parent.getUnitId(), 1));
			for (IChildUnit child : parent.getChildren()) {
				countList.add(new UnitCount(child.getUnitId(), child.getAmount()));
			}
		}
		return countList;
	}

}
